package com.wsc.crawler;

import java.io.File;
import java.io.FileNotFoundException;

import org.apache.log4j.Logger;

import com.wsc.crawler.grabber.Grabber;
import com.wsc.crawler.grabber.URLBeanQueue;
import com.wsc.crawler.init.CrawlerConfig;
import com.wsc.crawler.init.Initializer;

public class WSCrawler {

	private CrawlerConfig config = null;
	private URLBeanQueue queue = null;
	private static Initializer crawlerinit = null;

	private static Logger log = Logger.getLogger(WSCrawler.class.getName());

	private static WSCrawler crawler;
	/*
	 * Initialize config object with the default configuration.
	 */
	
	private WSCrawler(){

				// Initialize crawler resources with Initializer obj

				crawlerinit = new Initializer(config);
				
				// Create a WSCrawler Object and supply Initializer object.

				this.config = crawlerinit.getConfig();

	}

	 

	
	// return instance of the crawler.
	
	public static WSCrawler getInstance(){
		
		if(crawler == null){
			crawler = new WSCrawler();
		}
		return crawler;
	}
	
	
	
	public boolean isAnotherInstanceRunning() {

		if (crawler != null) {
			return true;
		}
		return false;

	}


	public void setConfig(CrawlerConfig config) {
		
		this.config = config;
		
	}
	
	public void startCrawler() {
		
		// create Gabber instance. 
		
		Grabber grabber = new Grabber(config);
		
		// set Seed URLs in grabber
		
		grabber.setFrontier(queue);
		
		// Start grabber.
		grabber.startGrabber();
	}

	/*
	 * nullify all objects used in this class. this method is useful when an
	 * exception or a fatal error occur.
	 */

	private void clear() {
		this.config = null;
		this.queue = null;
		crawlerinit = null;
	}

	/*
	 * Initialize config object with the default configuration.
	 */

	/**
	 * @param args
	 * @throws FileNotFoundException
	 */

	public static void main(String[] args) throws FileNotFoundException {

		// Crawler Configuration holder.

		CrawlerConfig config = new CrawlerConfig();

		// Load default config file from config dir.

		config.loadXmlFile(null);

		// Initialize crawler resources with Initializer obj

		crawlerinit = new Initializer(config);

		// Initialize frontier, indexer etc

		// start heartbeat server in a separate thread.
 	//	crawlerinit.startHeartBeatServer();			
	
		// Create a WSCrawler Object and supply Initializer object.

		WSCrawler crawler = new WSCrawler();

		crawler.initCrawler();

		long start = System.currentTimeMillis();

		// if everything fine start crawler.

		crawler.startCrawler();

		long end = System.currentTimeMillis();

		System.out.println("Crawling time is :" + (end - start));

		// If everything is fine then cleanup the instance data(Ex: lock files,
		// and any temp xml files).

		crawler.cleanStop();
	}

	// This method deletes any temp data stored in temp Dir while crawler
	// Running.

	private void cleanStop() {

		log.debug("Cleaning Crawler resources.");

		// Create a File object with lock file.

		File lockfile = new File(config.getTmp_dir() + "/crawler.lock");

		// check the existence of the lockfile if it exists, then delete it.
		if (lockfile.exists()) {
			log.debug("Deleting Lock file");
			lockfile.deleteOnExit();
			log.debug("Lock file Deleted");
		}
		// call static method in Intializer class to delete crawler.running file.
	}

	public void initCrawler() {

		// before starting crawler, intialize Frontier, and check Connection to
		// the Frontier Server.
		queue = crawlerinit.intializeFrotier();

		// And intialize Indexer, and check Connection to the Indexer Server.

		// indexer= Indexer initialization line

		if (this.queue == null || this.queue.isEmpty()) {
			log.fatal("Frontier Intialization is Unsuccessfull.");
			log.fatal("Exiting Crawler.");
			
			WSCrawler.stopInstance();
		}

	}

	// This method sets null to the current instance od the crawler.
	public static void stopInstance() {
		if(crawler !=null)
			crawler = null;
	}

}
